home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 42 / Amiga Format AFCD42 (Issue 126, Aug 1999).iso / -serious- / programming / other / jikes / src / getclass.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1999-05-14  |  44.4 KB  |  1,118 lines

  1. // $Id: getclass.cpp,v 1.7 1999/03/09 14:37:17 shields Exp $
  2. //
  3. // This software is subject to the terms of the IBM Jikes Compiler
  4. // License Agreement available at the following URL:
  5. // http://www.ibm.com/research/jikes.
  6. // Copyright (C) 1996, 1998, International Business Machines Corporation
  7. // and others.  All Rights Reserved.
  8. // You must accept the terms of that agreement to use this software.
  9. //
  10. #include "config.h"
  11. #include <sys/stat.h>
  12. #include "control.h"
  13. #include "semantic.h"
  14. #include "access.h"
  15. #include "getclass.h"
  16. #include "zip.h"
  17.  
  18. inline u1 Semantic::GetU1(char *buffer)
  19. {
  20.     return *buffer;
  21. }
  22.  
  23. inline u2 Semantic::GetU2(char *buffer)
  24. {
  25.     u2 i = (u1) *buffer++;
  26.     return (i << 8) + (u1) *buffer;
  27. }
  28.  
  29. inline u4 Semantic::GetU4(char *buffer)
  30. {
  31.     u4 i = (u1) *buffer++;
  32.     i = (i << 8) + (u1) *buffer++;
  33.     i = (i << 8) + (u1) *buffer++;
  34.     return (i << 8) + (u1) *buffer;
  35. }
  36.  
  37. inline u1 Semantic::GetAndSkipU1(char *&buffer)
  38. {
  39.     return (u1) *buffer++;
  40. }
  41.  
  42. inline u2 Semantic::GetAndSkipU2(char *&buffer)
  43. {
  44.     u2 i = (u1) *buffer++;
  45.     return (i << 8) + (u1) *buffer++;
  46. }
  47.  
  48. inline u4 Semantic::GetAndSkipU4(char *&buffer)
  49. {
  50.     u4 i = (u1) *buffer++;
  51.     i = (i << 8) + (u1) *buffer++;
  52.     i = (i << 8) + (u1) *buffer++;
  53.     return (i << 8) + (u1) *buffer++;
  54. }
  55.  
  56. inline void Semantic::Skip(char *&buffer, int n)
  57. {
  58.     buffer += n;
  59. }
  60.  
  61.  
  62. TypeSymbol *Semantic::ProcessNestedType(TypeSymbol *base_type, NameSymbol *name_symbol, LexStream::TokenIndex tok)
  63. {
  64.     TypeSymbol *inner_type = base_type -> FindTypeSymbol(name_symbol);
  65.     if (! inner_type)
  66.     {
  67.         int length = base_type -> ExternalNameLength() + 1 + name_symbol -> NameLength(); // +1 for $,... +1 for $
  68.         wchar_t *external_name = new wchar_t[length + 1]; // +1 for '\0';
  69.         wcscpy(external_name, base_type -> ExternalName());
  70.         wcscat(external_name, StringConstant::US__DS_);
  71.         wcscat(external_name, name_symbol -> Name());
  72.         NameSymbol *external_name_symbol = control.FindOrInsertName(external_name, length);
  73.  
  74.         delete [] external_name;
  75.  
  76.         inner_type = base_type -> InsertNestedTypeSymbol(name_symbol);
  77.         inner_type -> outermost_type = base_type -> outermost_type;
  78.         inner_type -> supertypes_closure = new SymbolSet;
  79.         inner_type -> subtypes = new SymbolSet;
  80.         inner_type -> SetExternalIdentity(external_name_symbol);
  81.         inner_type -> SetOwner(base_type);
  82.         inner_type -> SetSignature(control);
  83.  
  84.         FileSymbol *file_symbol = Control::GetFile(base_type -> ContainingPackage(), external_name_symbol, control.option.depend);
  85.         if (file_symbol)
  86.         {
  87.             inner_type -> file_symbol = file_symbol;
  88.             inner_type -> SetLocation();
  89.  
  90.             ReadClassFile(inner_type, tok);
  91.         }
  92.         else
  93.         {
  94.             inner_type -> SetSymbolTable(1); // this symbol table will only contain a default constructor
  95.             inner_type -> super = control.Object();
  96.             inner_type -> MarkBad();
  97.             AddDefaultConstructor(inner_type);
  98.             ReportSemError(SemanticError::TYPE_NOT_FOUND,
  99.                            tok,
  100.                            tok,
  101.                            inner_type -> ContainingPackage() -> PackageName(),
  102.                            inner_type -> ExternalName());
  103.         }
  104.     }
  105.  
  106.     return inner_type;
  107. }
  108.  
  109.  
  110. TypeSymbol *Semantic::RetrieveNestedTypes(TypeSymbol *base_type, wchar_t *signature, LexStream::TokenIndex tok)
  111. {
  112.     int len;
  113.     for (len = 0; signature[len] != U_NULL && signature[len] != U_DOLLAR; len++)
  114.         ;
  115.     NameSymbol *name_symbol = control.FindOrInsertName(signature, len);
  116.     TypeSymbol *inner_type = ProcessNestedType(base_type, name_symbol, tok);
  117.  
  118.     return (signature[len] == U_DOLLAR ? RetrieveNestedTypes(inner_type, &signature[len + 1], tok) : inner_type);
  119. }
  120.  
  121.  
  122. TypeSymbol *Semantic::ReadType(TypeSymbol *base_type, wchar_t *signature, LexStream::TokenIndex tok)
  123. {
  124.     int total_length;
  125.  
  126.     for (total_length = 0; signature[total_length] != U_NULL && signature[total_length] != U_DOLLAR; total_length++)
  127.         ;
  128.     if (signature[total_length] != U_NULL && Code::IsDigit(signature[total_length + 1])) // an anonymous or a local type?
  129.     {
  130.         for (total_length += 2; Code::IsDigit(signature[total_length]); total_length++) // will stop at next '$' or '\0' !!!
  131.             ;
  132.         if (signature[total_length] != U_NULL) // not an anonymous type ?  then, it's a local type: scan local name
  133.         {
  134.             for (total_length++; signature[total_length] != U_NULL && signature[total_length] != U_DOLLAR; total_length++)
  135.                 ;
  136.         }
  137.     }
  138.  
  139.     int len;
  140.     for (len = total_length - 1; len >= 0 && signature[len] != U_SLASH; len--)
  141.         ;
  142.  
  143.     wchar_t *name = &(signature[len + 1]);
  144.  
  145.     //
  146.     // When a package name is specified in the signature, we look for the type in question
  147.     // in that package, i.e., we redefine package. Otherwise, we search for the type in the
  148.     // unnamed package.
  149.     //
  150.     PackageSymbol *package = NULL;
  151.  
  152.     //
  153.     // Which package?
  154.     //
  155.     if (len >= 0)
  156.     {
  157.         wchar_t *package_name = new wchar_t[len + 1];
  158.         for (int i = 0; i < len; i++)
  159.             package_name[i] = signature[i];
  160.         package_name[len] = U_NULL;
  161.         package = control.ProcessPackage(package_name);
  162.  
  163.         if (package -> directory.Length() == 0)
  164.         {
  165.             ReportSemError(SemanticError::PACKAGE_NOT_FOUND,
  166.                            tok,
  167.                            tok,
  168.                            package -> PackageName());
  169.         }
  170.         delete [] package_name;
  171.     }
  172.     else package = control.unnamed_package;
  173.  
  174.     //
  175.     // Process type
  176.     //
  177.     NameSymbol *name_symbol = control.FindOrInsertName(name, total_length - (len + 1));
  178.     TypeSymbol *type = package -> FindTypeSymbol(name_symbol);
  179.     if (type)
  180.     {
  181.         if (type -> SourcePending())
  182.             control.ProcessHeaders(type -> file_symbol);
  183.     }
  184.     else
  185.     {
  186.         FileSymbol *file_symbol = Control::GetFile(package, name_symbol, control.option.depend);
  187.  
  188.         //
  189.         // If we are dealing with the unnamed package, ...
  190.         //
  191.         if ((! file_symbol) && package == control.unnamed_package)
  192.             file_symbol = Control::GetFile(control.unnamed_package, name_symbol, control.option.depend);
  193.  
  194.         //
  195.         // If a file_symbol was not found, ReadType will issue an error message
  196.         //
  197.         type = ReadType(file_symbol, package, name_symbol, tok);
  198.  
  199.         //
  200.         // If we have to do a full check and we have a case where a ".class" file
  201.         // depends on a ".java" file then we should signal that the ".java" file
  202.         // associated with the ".class" file should be recompiled.
  203.         //
  204.         if (control.option.full_check && (! control.option.depend) &&
  205.             file_symbol && file_symbol -> IsJava() && (! file_symbol -> IsZip()))
  206.         {
  207.             control.recompilation_file_set.AddElement(file_symbol);
  208.             if (! control.option.incremental && control.option.pedantic)
  209.             {
  210.                 ReportSemError(SemanticError::RECOMPILATION,
  211.                                tok,
  212.                                tok,
  213.                                base_type -> ContainingPackage() -> Name(), 
  214.                                base_type -> ExternalName(), 
  215.                                type -> ContainingPackage() -> Name(), 
  216.                                type -> ExternalName());
  217.             }
  218.         }
  219.     }
  220.  
  221.     //
  222.     // Establish a dependence from base_type (read from a class file) to type.
  223.     //
  224.     AddDependence(base_type, type, tok);
  225.  
  226.     return (signature[total_length] == U_DOLLAR ? RetrieveNestedTypes(type, &signature[total_length + 1], tok) : type);
  227. }
  228.  
  229.  
  230. TypeSymbol *Semantic::ProcessSignature(TypeSymbol *base_type, char *signature, LexStream::TokenIndex tok)
  231. {
  232.     TypeSymbol *type;
  233.     int num_dimensions = 0;
  234.  
  235.     for (; *signature == U_LEFT_BRACKET; signature++)
  236.         num_dimensions++;
  237.  
  238.     switch(*signature)
  239.     {
  240.         case U_B:
  241.              type = control.byte_type;
  242.              break;
  243.         case U_C:
  244.              type = control.char_type;
  245.              break;
  246.         case U_D:
  247.              type = control.double_type;
  248.              break;
  249.         case U_F:
  250.              type = control.float_type;
  251.              break;
  252.         case U_I:
  253.              type = control.int_type;
  254.              break;
  255.         case U_J:
  256.              type = control.long_type;
  257.              break;
  258.         case U_L:
  259.              {
  260.                  //
  261.                  // The signature is of the form: "L<filename>;" - So, +1 to skip the 'L'
  262.                  //
  263.                  char *str;
  264.                  for (str = signature++; *str != U_SEMICOLON; str++)
  265.                      ;
  266.                  int len = str - signature;
  267.                  wchar_t *type_name = new wchar_t[len + 1];
  268.                  ConvertUtf8ToUnicode(type_name, signature, len);
  269.                  type = ReadType(base_type, type_name, tok);
  270.                  delete [] type_name;
  271.              }
  272.              break;
  273.         case U_S:
  274.              type = control.short_type;
  275.              break;
  276.         case U_Z:
  277.              type = control.boolean_type;
  278.              break;
  279.         case U_V:
  280.              type = control.void_type;
  281.              break;
  282.         default:
  283.             assert(! "KNOW WHAT TO DO WITH SIGNATURE");
  284.             break;
  285.     }
  286.  
  287.     return (num_dimensions == 0 ? type : type -> GetArrayType((Semantic *)this, num_dimensions));
  288. }
  289.  
  290.  
  291. inline TypeSymbol *Semantic::GetClassPool(TypeSymbol *base_type,
  292.                                           TypeSymbol **class_pool,
  293.                                           char **constant_pool,
  294.                                           int index,
  295.                                           LexStream::TokenIndex tok)
  296. {
  297.     if (! class_pool[index])
  298.     {
  299.         u2 name_index = Constant_Class_info::NameIndex(constant_pool[index]);
  300.         char *str = Constant_Utf8_info::Bytes(constant_pool[name_index]);
  301.  
  302.         if (*str == U_LEFT_BRACKET)
  303.             class_pool[index] = ProcessSignature(base_type, str, tok);
  304.         else
  305.         {
  306.             u2 length = Constant_Utf8_info::Length(constant_pool[name_index]);
  307.             char *p;
  308.             for (p = &str[length - 1]; Code::IsDigit(*p); p--)
  309.                 ;
  310.             if (*p != U_DOLLAR) // not an anonymous class
  311.             {
  312.                 wchar_t *type_name = new wchar_t[length + 1];
  313.                 ConvertUtf8ToUnicode(type_name, str, length);
  314.                 class_pool[index] = ReadType(base_type, type_name, tok);
  315.                 delete [] type_name;
  316.             }
  317.         }
  318.     }
  319.  
  320.     return class_pool[index];
  321. }
  322.  
  323.  
  324. void Semantic::ReadClassFile(TypeSymbol *type, LexStream::TokenIndex tok)
  325. {
  326. #ifdef TEST
  327.     control.class_file_id++;
  328.     control.class_files_read++;
  329. #endif
  330.  
  331.     FileSymbol *file_symbol = type -> file_symbol;
  332.  
  333.     if (control.option.verbose)  {
  334.         cout << "[read ";
  335.         Unicode::Cout(file_symbol -> FileName());
  336.         cout << "]\n";
  337.     }
  338.  
  339.     if (file_symbol -> IsZip())
  340.     {
  341.         ZipFile *zipfile = new ZipFile(file_symbol);
  342.  
  343.         if (zipfile -> Buffer() == NULL)
  344.         {
  345.             type -> SetSymbolTable(1); // this symbol table will only contain a default constructor
  346.             if (type != control.Object())
  347.                 type -> super = (type == control.Throwable() ? control.Object() : control.Throwable());
  348.             type -> MarkBad();
  349.             AddDefaultConstructor(type);
  350.  
  351.             ReportSemError(SemanticError::COMPRESSED_ZIP_FILE,
  352.                            tok,
  353.                            tok,
  354.                            file_symbol -> PathSym() -> Name(),
  355.                            type -> ContainingPackage() -> PackageName(),
  356.                            type -> ExternalName());
  357.         }
  358.         else if (! ProcessClassFile(type, zipfile -> Buffer(), file_symbol -> uncompressed_size, tok))
  359.             ProcessBadClass(type, tok);
  360.  
  361.         delete zipfile;
  362.     }
  363.     else
  364.     {
  365. #if defined(UNIX_FILE_SYSTEM) || defined(AMIGAOS_FILE_SYSTEM)
  366.         FILE *classfile = ::SystemFopen(file_symbol -> FileName(), "rb");
  367.         if (classfile == NULL)
  368.         {
  369.             type -> SetSymbolTable(1); // this symbol table will only contain a default constructor
  370.             if (type != control.Object())
  371.                 type -> super = (type == control.Throwable() ? control.Object() : control.Throwable());
  372.             type -> MarkBad();
  373.             AddDefaultConstructor(type);
  374.  
  375.             ReportSemError(SemanticError::CANNOT_OPEN_CLASS_FILE,
  376.                            tok,
  377.                            tok,
  378.                            type -> ContainingPackage() -> PackageName(),
  379.                            type -> ExternalName());
  380.         }
  381.         else
  382.         {
  383.             struct stat status;
  384.             ::SystemStat(file_symbol -> FileName(), &status);
  385.  
  386.             char *class_buffer = new char[status.st_size];
  387.             fread(class_buffer, sizeof(char), status.st_size, classfile);
  388.             fclose(classfile);
  389.  
  390.             if (! ProcessClassFile(type, class_buffer, status.st_size, tok))
  391.                 ProcessBadClass(type, tok);
  392.  
  393.             delete [] class_buffer;
  394.         }
  395. #elif defined(WIN32_FILE_SYSTEM)
  396.         HANDLE classfile = CreateFile(file_symbol -> FileName(), GENERIC_READ, FILE_SHARE_READ,
  397.                                       NULL, OPEN_EXISTING, FILE_ATTRIBUTE_READONLY, NULL);
  398.         HANDLE mapfile = (classfile == INVALID_HANDLE_VALUE
  399.                                      ? classfile
  400.                                      : CreateFileMapping(classfile, NULL, PAGE_READONLY, 0, 0, NULL));
  401.  
  402.         char *class_buffer = (mapfile == INVALID_HANDLE_VALUE ? NULL : (char *) MapViewOfFile(mapfile, FILE_MAP_READ, 0, 0, 0));
  403.  
  404.         if (class_buffer == NULL)
  405.         {
  406.             type -> SetSymbolTable(1); // this symbol table will only contain a default constructor
  407.             if (type != control.Object())
  408.                 type -> super = (type == control.Throwable() ? control.Object() : control.Throwable());
  409.             type -> MarkBad();
  410.             AddDefaultConstructor(type);
  411.  
  412.             ReportSemError(SemanticError::CANNOT_OPEN_CLASS_FILE,
  413.                            tok,
  414.                            tok,
  415.                            type -> ContainingPackage() -> PackageName(), 
  416.                            type -> ExternalName());
  417.         }
  418.         else
  419.         {
  420.             DWORD high_order,
  421.                   size = GetFileSize(classfile, &high_order);
  422.  
  423.             size = (size == 0xFFFFFFFF && GetLastError() != NO_ERROR ? 0 : size);
  424.  
  425.             if (! ProcessClassFile(type, class_buffer, size, tok))
  426.                 ProcessBadClass(type, tok);
  427.  
  428.             UnmapViewOfFile(class_buffer);
  429.             CloseHandle(mapfile);
  430.             CloseHandle(classfile);
  431.         }
  432. #endif
  433.     }
  434.  
  435.     return;
  436. }
  437.  
  438.  
  439. void Semantic::ProcessBadClass(TypeSymbol *type, LexStream::TokenIndex tok)
  440. {
  441.     if (! type -> Table()) // if there is no symbol table, add one
  442.         type -> SetSymbolTable(1); // this symbol table will only contain a default constructor
  443.     if ((! type -> super) && type != control.Object()) // if there is no super type, add one
  444.         type -> super = (type == control.Throwable() ? control.Object() : control.Throwable());
  445.     type -> MarkBad();
  446.     if (! type -> FindConstructorSymbol()) // if there are no constructors, add a default one
  447.         AddDefaultConstructor(type);
  448.  
  449.     ReportSemError(SemanticError::INVALID_CLASS_FILE,
  450.                    tok,
  451.                    tok,
  452.                    type -> ContainingPackage() -> PackageName(),
  453.                    type -> ExternalName());
  454.  
  455.     return;
  456. }
  457.  
  458.  
  459. bool Semantic::ProcessClassFile(TypeSymbol *type, char *buffer, int buffer_size, LexStream::TokenIndex tok)
  460. {
  461.     char *buffer_tail = &buffer[buffer_size];
  462.  
  463.     type -> MarkHeaderProcessed();
  464.     type -> MarkConstructorMembersProcessed();
  465.     type -> MarkMethodMembersProcessed();
  466.     type -> MarkFieldMembersProcessed();
  467.     type -> MarkLocalClassProcessingCompleted();
  468.     type -> MarkSourceNoLongerPending();
  469.  
  470.     Skip(buffer, 8); // u4 magic;
  471.                      // u2 minor_version;
  472.                      // u2 major_version;
  473.  
  474.     if (! InRange(buffer, buffer_tail, 2))
  475.         return false;
  476.     u2 constant_pool_count = GetAndSkipU2(buffer);
  477.     char **constant_pool = new char*[constant_pool_count];
  478.     TypeSymbol **class_pool = (TypeSymbol **)
  479.                               memset(new TypeSymbol*[constant_pool_count], 0, constant_pool_count * sizeof(TypeSymbol *));
  480.  
  481.     constant_pool[0] = NULL;
  482.     int *next_pool_index = new int[constant_pool_count],
  483.         Class_root = 0,
  484.         NameAndType_root = 0;
  485.  
  486.     for (int i = 1; i < constant_pool_count; i++)
  487.     {
  488.         constant_pool[i] = buffer;
  489.         if (! InRange(buffer, buffer_tail, 1))
  490.             return false;
  491.         u1 tag = GetAndSkipU1(buffer);
  492.         if (tag == Cp_Info::CONSTANT_Long || tag == Cp_Info::CONSTANT_Double)
  493.             ++i; // skip the next entry for eight-byte constants
  494.  
  495.         u2 length;
  496.         switch(tag)
  497.         {
  498.             case Cp_Info::CONSTANT_Utf8:
  499.                  if (! InRange(buffer, buffer_tail, 2))
  500.                      return false;
  501.                  length = GetAndSkipU2(buffer);
  502.                  break;
  503.             case Cp_Info::CONSTANT_Class:
  504.                  length = 2;                      // set_NameIndex(GetU2(classfile));
  505.                  next_pool_index[i] = Class_root; // save index of class constant
  506.                  Class_root = i;
  507.                  break;
  508.             case Cp_Info::CONSTANT_String:
  509.                  length = 2; // set_NameIndex(GetU2(classfile));
  510.                  break;
  511.             case Cp_Info::CONSTANT_NameAndType:
  512.                  length = 4; // set_class_index(GetU2(classfile)); set_name_and_type_index(GetU2(classfile));
  513.                              //                                     or
  514.                              // set_NameIndex(GetU2(classfile)); set_DescriptorIndex(GetU2(classfile));
  515.                              //                                     or
  516.                              // SetBytes(GetU4(classfile));
  517.                  next_pool_index[i] = NameAndType_root; // save index of class constant
  518.                  NameAndType_root = i;
  519.                  break;
  520.             case Cp_Info::CONSTANT_Fieldref:
  521.             case Cp_Info::CONSTANT_Methodref:
  522.             case Cp_Info::CONSTANT_InterfaceMethodref:
  523.             case Cp_Info::CONSTANT_Integer:
  524.             case Cp_Info::CONSTANT_Float:
  525.                  length = 4; // set_class_index(GetU2(classfile)); set_name_and_type_index(GetU2(classfile));
  526.                              //                                     or
  527.                              // set_NameIndex(GetU2(classfile)); set_DescriptorIndex(GetU2(classfile));
  528.                              //                                     or
  529.                              // SetBytes(GetU4(classfile));
  530.                  break;
  531.             case Cp_Info::CONSTANT_Long:
  532.             case Cp_Info::CONSTANT_Double:
  533.                  length = 8; // set_HighBytes(GetU4(classfile));
  534.                              // set_LowBytes(GetU4(classfile));
  535.     
  536.                  break;
  537.             default:
  538. cerr << "chaos: CODE \"" << (int) tag << "\" is an invalid tag !!!\n";
  539. cerr.flush();
  540.                  break;
  541.         }
  542.  
  543.         Skip(buffer, length);
  544.     }
  545.  
  546.     //
  547.     // We are now ready to process this class file. If type is a nested
  548.     // class, we will set its untransformed access flags properly later...
  549.     //
  550.     if (! InRange(buffer, buffer_tail, 2))
  551.         return false;
  552.     type -> access_flags = GetAndSkipU2(buffer);
  553.  
  554.     if (! InRange(buffer, buffer_tail, 2))
  555.         return false;
  556.     u2 this_class_index = GetAndSkipU2(buffer); // The index of this class
  557.     u2 name_index = Constant_Class_info::NameIndex(constant_pool[this_class_index]);
  558.     char *type_name = Constant_Utf8_info::Bytes(constant_pool[name_index]);
  559.     u2 type_name_length = Constant_Utf8_info::Length(constant_pool[name_index]);
  560.  
  561.     int n;
  562.     for (n = type_name_length; n >= 0 && type_name[n] != U_SLASH; n--)
  563.         ;
  564.  
  565.     bool matched_package_names;
  566.     if (type -> ContainingPackage() -> PackageNameLength() == n)
  567.     {
  568.         wchar_t *package_name = type -> ContainingPackage() -> PackageName();
  569.         int i;
  570.         for (i = 0; i < n && package_name[i] == type_name[i]; i++)
  571.             ;
  572.         matched_package_names = (i == n);
  573.     }
  574.     else matched_package_names = (n < 0 && type -> ContainingPackage() == control.unnamed_package);
  575.  
  576.     if (! matched_package_names)
  577.     {
  578.         type -> SetSymbolTable(1); // this symbol table will only contain a default constructor
  579.         if (type != control.Object())
  580.             type -> super = (type == control.Throwable() ? control.Object() : control.Throwable());
  581.         type -> MarkBad();
  582.         AddDefaultConstructor(type);
  583.  
  584.         if (n < 0)
  585.             n = 0;
  586.         wchar_t *package_name = new wchar_t[n + 1];
  587.         for (int i = 0; i < n; i++)
  588.             package_name[i] = type_name[i];
  589.         package_name[n] = U_NULL;
  590.  
  591.         if (type -> ContainingPackage() == control.unnamed_package)
  592.              ReportSemError(SemanticError::TYPE_NOT_IN_UNNAMED_PACKAGE,
  593.                             tok,
  594.                             tok,
  595.                             type -> ExternalName(),
  596.                             type -> file_symbol -> directory_symbol -> PathSym() -> Name(),
  597.                             package_name);
  598.         else ReportSemError(SemanticError::TYPE_IN_WRONG_PACKAGE,
  599.                             tok,
  600.                             tok,
  601.                             type -> ExternalName(),
  602.                             type -> ContainingPackage() -> PackageName(),
  603.                             package_name);
  604.     
  605.         delete [] package_name;
  606.     }
  607.     else
  608.     {
  609.         if ((! type -> IsNested()) && (n < 0)) // An outermost type contained in the unnamed package?
  610.         {
  611.             TypeSymbol *old_type = (TypeSymbol *) control.unnamed_package_types.Image(type -> Identity());
  612.             if (! old_type)
  613.                 control.unnamed_package_types.AddElement(type);
  614.             else
  615.             {
  616.                 ReportSemError(SemanticError::DUPLICATE_TYPE_DECLARATION,
  617.                                tok,
  618.                                tok,
  619.                                type -> Name(),
  620.                                old_type -> FileLoc());
  621.             }
  622.         }
  623.  
  624.         //
  625.         // On systems such as NT and Win-95 that are not case-sensitive,
  626.         // we need to confirm that the type name specified matches the name
  627.         // in the class file.
  628.         //
  629. assert(type_name_length - (n + 1) == type -> ExternalNameLength());
  630.         int i;
  631.         for (i = 0; i < type -> ExternalNameLength(); i++)
  632.         {
  633.             if (type_name[(n + 1) + i] != type -> ExternalName()[i])
  634.                 break;
  635.         }
  636.         if (i < type -> ExternalNameLength())
  637.         {
  638.             wchar_t *name = new wchar_t[type_name_length + 1];
  639.             for (int k = 0; k < type_name_length; k++)
  640.                 name[k] = type_name[k];
  641.             name[type_name_length] = U_NULL;
  642.             ReportSemError(SemanticError::TYPE_NAME_MISMATCH,
  643.                            tok,
  644.                            tok,
  645.                            type -> ContainingPackage() -> PackageName(),
  646.                            type -> ExternalName(),
  647.                            name);
  648.             delete [] name;
  649.         }
  650.  
  651.         //
  652.         // ... Start doing real work !!!
  653.         //
  654.         if (! InRange(buffer, buffer_tail, 2))
  655.             return false;
  656.         u2 super_class = GetAndSkipU2(buffer);
  657.         if (super_class)
  658.         {
  659.             type -> super = GetClassPool(type, class_pool, constant_pool, super_class, tok);
  660.  
  661.             type -> outermost_type -> supertypes_closure -> AddElement(type -> super -> outermost_type);
  662.             type -> outermost_type -> supertypes_closure -> Union(*type -> super -> outermost_type -> supertypes_closure);
  663.         }
  664.  
  665.         if (! InRange(buffer, buffer_tail, 2))
  666.             return false;
  667.         for (int j = GetAndSkipU2(buffer); j > 0; j--)
  668.         {
  669.             if (! InRange(buffer, buffer_tail, 2))
  670.                 return false;
  671.             u2 interface_index = GetAndSkipU2(buffer);
  672.             type -> AddInterface(GetClassPool(type, class_pool, constant_pool, interface_index, tok));
  673.  
  674.             type -> outermost_type -> supertypes_closure -> AddElement(type -> super -> outermost_type);
  675.             type -> outermost_type -> supertypes_closure -> Union(*type -> super -> outermost_type -> supertypes_closure);
  676.         }
  677.  
  678.         //
  679.         // Read all the fields
  680.         //
  681.         if (! InRange(buffer, buffer_tail, 2))
  682.             return false;
  683.         u2 fields_count = GetAndSkipU2(buffer);
  684.         VariableSymbol **fields = new VariableSymbol*[fields_count];
  685.         for (int k = 0; k < fields_count; k++)
  686.         {
  687.             if (! InRange(buffer, buffer_tail, 6))
  688.                 return false;
  689.             u2 access_flags = GetAndSkipU2(buffer);
  690.             u2 name_index = GetAndSkipU2(buffer);
  691.             u2 descriptor_index = GetAndSkipU2(buffer);
  692.  
  693.             u2 length = Constant_Utf8_info::Length(constant_pool[name_index]);
  694.             wchar_t *variable_name = new wchar_t[length + 1];
  695.             ConvertUtf8ToUnicode(variable_name, Constant_Utf8_info::Bytes(constant_pool[name_index]), length);
  696.             NameSymbol *name_symbol = control.FindOrInsertName(variable_name, length);
  697.             delete [] variable_name;
  698.  
  699.             VariableSymbol *symbol = new VariableSymbol(name_symbol);
  700.             fields[k] = symbol;
  701.  
  702.             symbol -> SetOwner(type);
  703.             symbol -> MarkComplete();
  704.             symbol -> SetFlags(access_flags);
  705.             symbol -> SetSignatureString(Constant_Utf8_info::Bytes(constant_pool[descriptor_index]),
  706.                                          Constant_Utf8_info::Length(constant_pool[descriptor_index]));
  707.  
  708.             if (! InRange(buffer, buffer_tail, 2))
  709.                 return false;
  710.             int j = GetAndSkipU2(buffer);
  711.             for (; j > 0; j--)
  712.             {
  713.                 if (! InRange(buffer, buffer_tail, 2))
  714.                     return false;
  715.                 u2 name_index = GetAndSkipU2(buffer);
  716.  
  717.                 if (Constant_Utf8_info::Length(constant_pool[name_index]) == StringConstant::U8S_Synthetic_length &&
  718.                     memcmp(Constant_Utf8_info::Bytes(constant_pool[name_index]),
  719.                            StringConstant::U8S_Synthetic, StringConstant::U8S_Synthetic_length * sizeof(char)) == 0)
  720.                 {
  721.                     symbol -> MarkSynthetic();
  722.                     if (! InRange(buffer, buffer_tail, 4))
  723.                         return false;
  724.                     Skip(buffer, 4); // u4 attribute_length() { return attribute_length_; }
  725.                                      // there is no info associated with a Synthetic attribute
  726.                     break; // If the field is synthetic, remaining attributes don't matter...
  727.                 }
  728.                 else if (Constant_Utf8_info::Length(constant_pool[name_index]) == StringConstant::U8S_ConstantValue_length &&
  729.                          memcmp(Constant_Utf8_info::Bytes(constant_pool[name_index]),
  730.                                 StringConstant::U8S_ConstantValue, StringConstant::U8S_ConstantValue_length * sizeof(char)) == 0)
  731.                 {
  732.                     Skip(buffer, 4); // u4 attribute_length; 
  733.                     if (! InRange(buffer, buffer_tail, 2))
  734.                         return false;
  735.                     u2 constantvalue_index = GetAndSkipU2(buffer);
  736.  
  737.                     u1 tag = Cp_Info::Tag(constant_pool[constantvalue_index]);
  738.                     if (tag == Cp_Info::CONSTANT_Integer)
  739.                     {
  740.                         int value = Constant_Integer_info::Value(constant_pool[constantvalue_index]);
  741.                         symbol -> initial_value = control.int_pool.FindOrInsert(value);
  742.                     }
  743.                     else if (tag == Cp_Info::CONSTANT_Long)
  744.                     {
  745.                         LongInt value = Constant_Long_info::Value(constant_pool[constantvalue_index]);
  746.                         symbol -> initial_value = control.long_pool.FindOrInsert(value);
  747.                     }
  748.                     else if (tag == Cp_Info::CONSTANT_Float)
  749.                     {
  750.                         IEEEfloat value = Constant_Float_info::Value(constant_pool[constantvalue_index]);
  751.                         symbol -> initial_value = control.float_pool.FindOrInsert(value);
  752.                     }
  753.                     else if (tag == Cp_Info::CONSTANT_Double)
  754.                     {
  755.                         IEEEdouble value = Constant_Double_info::Value(constant_pool[constantvalue_index]);
  756.                         symbol -> initial_value = control.double_pool.FindOrInsert(value);
  757.                     }
  758.                     else if (tag == Cp_Info::CONSTANT_String)
  759.                     {
  760.                         u2 string_index = Constant_String_info::StringIndex(constant_pool[constantvalue_index]);
  761.                         u2 length = Constant_Utf8_info::Length(constant_pool[string_index]);
  762.                         char *value = Constant_Utf8_info::Bytes(constant_pool[string_index]);
  763.                         symbol -> initial_value = control.Utf8_pool.FindOrInsert(value, length);
  764.                     }
  765.                     else if (tag == Cp_Info::CONSTANT_Utf8)
  766.                     {
  767.                         u2 length = Constant_Utf8_info::Length(constant_pool[constantvalue_index]);
  768.                         char *value = Constant_Utf8_info::Bytes(constant_pool[constantvalue_index]);
  769.                         symbol -> initial_value = control.Utf8_pool.FindOrInsert(value, length);
  770.                     }
  771. else
  772. {
  773. cerr << "chaos: Constant tag \"" << (int) tag << "\" is an invalid tag !!!\n";
  774. cerr.flush();
  775. }
  776.                 }
  777.                 else
  778.                 {
  779.                     if (! InRange(buffer, buffer_tail, 4))
  780.                         return false;
  781.                     Skip(buffer, GetAndSkipU4(buffer)); // u4 attribute_length() { return attribute_length_; }
  782.                                                         // u1 *info; /* info[attribute_length] */
  783.                 }
  784.             }
  785.  
  786.             //
  787.             // Skip remaining attributes
  788.             //
  789.             while (--j > 0)
  790.             {
  791.                 Skip(buffer, 2);                    // u2 name_index
  792.                 if (! InRange(buffer, buffer_tail, 4))
  793.                     return false;
  794.                 Skip(buffer, GetAndSkipU4(buffer)); // u4 attribute_length() { return attribute_length_; }
  795.                                                     // u1 *info; /* info[attribute_length] */
  796.             }
  797.         }
  798.  
  799.         //
  800.         // Read all the methods
  801.         //
  802.         if (! InRange(buffer, buffer_tail, 2))
  803.             return false;
  804.         u2 methods_count = GetAndSkipU2(buffer);
  805.         MethodSymbol **methods = new MethodSymbol*[methods_count];
  806.         for (int l = 0; l < methods_count; l++)
  807.         {
  808.             if (! InRange(buffer, buffer_tail, 6))
  809.                 return false;
  810.             u2 access_flags = GetAndSkipU2(buffer);
  811.             u2 name_index = GetAndSkipU2(buffer);
  812.             u2 descriptor_index = GetAndSkipU2(buffer);
  813.  
  814.             u2 length = Constant_Utf8_info::Length(constant_pool[name_index]);
  815.             wchar_t *method_name = new wchar_t[length + 1];
  816.             ConvertUtf8ToUnicode(method_name, Constant_Utf8_info::Bytes(constant_pool[name_index]), length);
  817.             NameSymbol *name_symbol = control.FindOrInsertName(method_name, length);
  818.             delete [] method_name;
  819.  
  820.             if (! InRange(buffer, buffer_tail, 2))
  821.                 return false;
  822.             int j = GetAndSkipU2(buffer); // number of attributes
  823.  
  824.             if (name_symbol == control.clinit_name_symbol)
  825.             {
  826.                 methods[l] = NULL;
  827.                 j++; // see the loop (way) below that skips the remaining attributes
  828.             }
  829.             else
  830.             {
  831.                 MethodSymbol *method = new MethodSymbol(name_symbol);
  832.                 methods[l] = method;
  833.  
  834.                 method -> SetContainingType(type);
  835.                 method -> SetFlags(access_flags);
  836.  
  837.                 char *signature = Constant_Utf8_info::Bytes(constant_pool[descriptor_index]);
  838.                 int length = Constant_Utf8_info::Length(constant_pool[descriptor_index]);
  839.  
  840.                 method -> SetSignature(control.Utf8_pool.FindOrInsert(signature, length));
  841.  
  842.                 //
  843.                 // Read the exception that can be thrown by this method
  844.                 //
  845.                 for (; j > 0; j--)
  846.                 {
  847.                     if (! InRange(buffer, buffer_tail, 2))
  848.                         return false;
  849.                     u2 name_index = GetAndSkipU2(buffer);
  850.  
  851.                     if (Constant_Utf8_info::Length(constant_pool[name_index]) == StringConstant::U8S_Synthetic_length &&
  852.                         memcmp(Constant_Utf8_info::Bytes(constant_pool[name_index]),
  853.                                StringConstant::U8S_Synthetic, StringConstant::U8S_Synthetic_length * sizeof(char)) == 0)
  854.                     {
  855.                         method -> MarkSynthetic();
  856.                         if (! InRange(buffer, buffer_tail, 4))
  857.                             return false;
  858.                         Skip(buffer, 4); // u4 attribute_length() { return attribute_length_; }
  859.                                          // there is no info associated with a Synthetic attribute
  860.                         break; // If the field is synthetic, remaining attributes don't matter...
  861.                     }
  862.                     else if (Constant_Utf8_info::Length(constant_pool[name_index]) == StringConstant::U8S_Exceptions_length &&
  863.                              memcmp(Constant_Utf8_info::Bytes(constant_pool[name_index]),
  864.                                     StringConstant::U8S_Exceptions, StringConstant::U8S_Exceptions_length * sizeof(char)) == 0)
  865.                     {
  866.                         Skip(buffer, 4); // attribute_length = GetAndSkipU4(buffer);
  867.                         if (! InRange(buffer, buffer_tail, 2))
  868.                             return false;
  869.                         for (int k = GetAndSkipU2(buffer); k > 0; k--)
  870.                         {
  871.                             if (! InRange(buffer, buffer_tail, 2))
  872.                                 return false;
  873.                             int index = GetAndSkipU2(buffer);
  874.                             u2 name_index = Constant_Class_info::NameIndex(constant_pool[index]);
  875.                             method -> AddThrowsSignature(Constant_Utf8_info::Bytes(constant_pool[name_index]),
  876.                                                          Constant_Utf8_info::Length(constant_pool[name_index]));
  877.                         }
  878.                     }
  879.                     else
  880.                     {
  881.                         if (! InRange(buffer, buffer_tail, 4))
  882.                             return false;
  883.                         Skip(buffer, GetAndSkipU4(buffer)); // u4 attribute_length() { return attribute_length_; }
  884.                                                             // u1 *info; /* info[attribute_length] */
  885.                     }
  886.                 }
  887.             }
  888.  
  889.             //
  890.             // Skip remaining attributes
  891.             //
  892.             while (--j > 0)
  893.             {
  894.                 Skip(buffer, 2);                     // u2 name_index
  895.                 if (! InRange(buffer, buffer_tail, 4))
  896.                     return false;
  897.                 Skip(buffer, GetAndSkipU4(buffer)); // u4 attribute_length() { return attribute_length_; }
  898.                                                     // u1 *info; /* info[attribute_length] */
  899.             }
  900.         }
  901.  
  902.         //
  903.         // Process InnerClasses attributes
  904.         //
  905.         if (! InRange(buffer, buffer_tail, 2))
  906.             return false;
  907.         u2 attributes_count = GetAndSkipU2(buffer);
  908.         Tuple<u2> inner_name_indexes(8);
  909.         for (int a = 0; a < attributes_count; a++)
  910.         {
  911.             if (! InRange(buffer, buffer_tail, 2))
  912.                 return false;
  913.             u2 name_index = GetAndSkipU2(buffer);
  914.                
  915.             if (Constant_Utf8_info::Length(constant_pool[name_index]) == StringConstant::U8S_InnerClasses_length &&
  916.                 memcmp(Constant_Utf8_info::Bytes(constant_pool[name_index]),
  917.                        StringConstant::U8S_InnerClasses, StringConstant::U8S_InnerClasses_length * sizeof(char)) == 0)
  918.             {
  919.                 Skip(buffer, 4); // attribute_length = GetAndSkipU4(buffer);
  920.                 if (! InRange(buffer, buffer_tail, 2))
  921.                     return false;
  922.                 for (int k = GetAndSkipU2(buffer); k > 0; k--)
  923.                 {
  924.                     if (! InRange(buffer, buffer_tail, 8))
  925.                         return false;
  926.                     u2 inner_class_info_index   = GetAndSkipU2(buffer);
  927.                     u2 outer_class_info_index   = GetAndSkipU2(buffer);
  928.                     u2 inner_name_index         = GetAndSkipU2(buffer);
  929.                     u2 inner_class_access_flags = GetAndSkipU2(buffer);
  930.  
  931.                     //
  932.                     // Recall that the untransformed access flag is the one specified
  933.                     // in the inner_class attribute. (See 1.1 document)
  934.                     //
  935.                     if (inner_class_info_index == this_class_index)
  936.                         type -> access_flags = inner_class_access_flags;
  937.                     //
  938.                     // This guard statement is used to identify only inner classes that are
  939.                     // not anonymous classes and are immediately contained within this class.
  940.                     // Recall that an inner class may not be enclosed (directly on indirectly)
  941.                     // in another class with the same name. Therefore when outer_class_info_index
  942.                     // matches this_class_index they both refer to "this" class (that we are currently processing).
  943.                     //
  944.                     else if ((outer_class_info_index == this_class_index) &&
  945.                              (inner_class_info_index != 0) &&                  // an inner class
  946.                              (inner_name_index != 0))                          // not an anonymous class
  947.                     {
  948.                         //
  949.                         // When length is 0, the inner class in question is "this" class ?
  950.                         // the one we are currently reading ?
  951.                         //
  952.                         u2 length = Constant_Utf8_info::Length(constant_pool[inner_name_index]);
  953.                         if (length > 0)
  954.                             inner_name_indexes.Next() = inner_name_index;
  955.                     }
  956.                 }
  957.  
  958.                 break; // We are only interested in the inner classes attribute
  959.             }
  960.             else
  961.             {
  962.                 if (! InRange(buffer, buffer_tail, 4))
  963.                     return false;
  964.                 Skip(buffer, GetAndSkipU4(buffer)); // u4 attribute_length() { return attribute_length_; }
  965.                                                     // u1 *info; /* info[attribute_length] */
  966.             }
  967.         }
  968.  
  969.         //
  970.         // No need to skip the remaining attributes
  971.         //
  972.         //        while (--j > 0)
  973.         //        {
  974.         //            Skip(buffer, 2);                    // u2 name_index
  975.         //            Skip(buffer, GetAndSkipU4(buffer)); // u4 attribute_length() { return attribute_length_; }
  976.         //                                                // u1 *info; /* info[attribute_length] */
  977.         //        }
  978.         //
  979.  
  980.         //
  981.         // We now have enough information to make a good estimate for the size of the
  982.         // symbol table we need for this class.
  983.         //
  984.         type -> SetSymbolTable(fields_count + methods_count + inner_name_indexes.Length());
  985.  
  986.         //
  987.         //   . Read in all class files that are referenced in CONSTANT_Class
  988.         //     structures in this class file.
  989.         //
  990.         //   . Read in all class files that are referenced in CONSTANT_NameAndType
  991.         //     structures in this class file.
  992.         //
  993.         if (control.option.full_check && (control.option.unzip || (! type -> file_symbol -> IsZip())))
  994.         {
  995.             for (int h = Class_root; h != 0; h = next_pool_index[h])
  996.                 GetClassPool(type, class_pool, constant_pool, h, tok);
  997.  
  998.             for (int j = NameAndType_root; j != 0; j = next_pool_index[j])
  999.             {
  1000.                 u2 descriptor_index = Constant_NameAndType_info::DescriptorIndex(constant_pool[j]);
  1001.                 char *signature = Constant_Utf8_info::Bytes(constant_pool[descriptor_index]);
  1002.  
  1003.                 if (! class_pool[descriptor_index])
  1004.                 {
  1005.                     if (*signature != U_LEFT_PARENTHESIS)  // ')' indicates a field descriptor
  1006.                         class_pool[descriptor_index] = ProcessSignature(type,
  1007.                                                                         Constant_Utf8_info::Bytes(constant_pool[descriptor_index]),
  1008.                                                                         tok);
  1009.                     else // a method descriptor
  1010.                     {
  1011.                         signature++; // +1 to skip initial '('
  1012.                         while (*signature != U_RIGHT_PARENTHESIS)
  1013.                         {
  1014.                             char *str;
  1015.                             for (str = signature; *str == U_LEFT_BRACKET; str++)
  1016.                                 ;
  1017.  
  1018.                             if (*str == U_L)
  1019.                             {
  1020.                                 for (str++; *str != U_SEMICOLON; str++)
  1021.                                     ;
  1022.                             }
  1023.  
  1024.                             int len = str - signature + 1;
  1025.                             signature += len; // make signature point to next type
  1026.                         }
  1027.                         signature++; // skip L')'
  1028.  
  1029.                         class_pool[descriptor_index] = ProcessSignature(type, signature, tok); // save the return type in first spot
  1030.                     }
  1031.                 }
  1032.             }
  1033.  
  1034.             //
  1035.             // Process all the fields, then the methods, then the inner types.
  1036.             // Read in all the types associated with the signatures.
  1037.             //
  1038.             for (int k = 0; k < fields_count; k++)
  1039.             {
  1040.                 type -> InsertVariableSymbol(fields[k]);
  1041.                 fields[k] -> ProcessVariableSignature((Semantic *) this, tok);
  1042.             }
  1043.  
  1044.             for (int l = 0; l < methods_count; l++)
  1045.             {
  1046.                 if (methods[l])
  1047.                 {
  1048.                     MethodSymbol *method = type -> FindMethodSymbol(methods[l] -> name_symbol);
  1049.  
  1050.                     if (! method)
  1051.                     {
  1052.                          if (methods[l] -> name_symbol == control.init_name_symbol)
  1053.                               type -> InsertConstructorSymbol(methods[l]);
  1054.                          else type -> InsertMethodSymbol(methods[l]);
  1055.                     }
  1056.                     else type -> Overload(method, methods[l]);
  1057.                     methods[l] -> ProcessMethodSignature((Semantic *) this, tok);
  1058.                 }
  1059.             }
  1060.  
  1061.             for (int m = 0; m < inner_name_indexes.Length(); m++)
  1062.             {
  1063.                 u2 inner_name_index = inner_name_indexes[m];
  1064.                 type -> AddNestedTypeSignature(Constant_Utf8_info::Bytes(constant_pool[inner_name_index]),
  1065.                                                Constant_Utf8_info::Length(constant_pool[inner_name_index]));
  1066.             }
  1067.             type -> ProcessNestedTypeSignatures((Semantic *) this, tok);
  1068.         }
  1069.         else
  1070.         {
  1071.             //
  1072.             // Process all the fields, then the methods, then the inner types.
  1073.             //
  1074.             for (int k = 0; k < fields_count; k++)
  1075.                 type -> InsertVariableSymbol(fields[k]);
  1076.  
  1077.             for (int l = 0; l < methods_count; l++)
  1078.             {
  1079.                 if (methods[l])
  1080.                 {
  1081.                     MethodSymbol *method = type -> FindMethodSymbol(methods[l] -> name_symbol);
  1082.  
  1083.                     if (! method)
  1084.                     {
  1085.                          if (methods[l] -> name_symbol == control.init_name_symbol)
  1086.                               type -> InsertConstructorSymbol(methods[l]);
  1087.                          else type -> InsertMethodSymbol(methods[l]);
  1088.                     }
  1089.                     else type -> Overload(method, methods[l]);
  1090.                 }
  1091.             }
  1092.  
  1093.             for (int m = 0; m < inner_name_indexes.Length(); m++)
  1094.             {
  1095.                 u2 inner_name_index = inner_name_indexes[m];
  1096.                 type -> AddNestedTypeSignature(Constant_Utf8_info::Bytes(constant_pool[inner_name_index]),
  1097.                                                Constant_Utf8_info::Length(constant_pool[inner_name_index]));
  1098.             }
  1099.         }
  1100.  
  1101.         delete [] fields;
  1102.         delete [] methods;
  1103.  
  1104.         //
  1105.         // Release extra space. This is an optimization.
  1106.         //
  1107.         type -> CompressSpace();
  1108.     }
  1109.  
  1110.     delete [] next_pool_index;
  1111.     delete [] class_pool;
  1112.     delete [] constant_pool;
  1113.  
  1114.     return true;
  1115. }
  1116.  
  1117.  
  1118.